<?php


namespace Lib;


use Lib\Component\Factory;

class Acrion
{
    const NAMESPACE = '\\App\\Controllers\\';
    private $controllerName = '';
    private $functionName = '';
    private $parameter = array();

    /**
     * 通过控制器名称和方法名称实例化行为
     * Acrion constructor.
     * @param $controllerName
     * @param $functionName
     */
    public function __construct($controllerName, $functionName)
    {
        if (!$controllerName) {
            $controllerName = 'index';
        }
        if (!$functionName) {
            $functionName = 'index';
        }
        // 拼接控制器类命名空间
        $this->controllerName = self::NAMESPACE . ucfirst($controllerName).'Controller';
        $this->functionName = $functionName;
    }

    /**
     * 执行行为
     * @return mixed
     * @throws \ReflectionException
     */
    public function run() {
        // 判断控制器是否存在
        if (!class_exists($this->controllerName)) {
            Handle::handle404();
        }

        // 实例化控制器对象
        $controller = new $this->controllerName();
        if (!method_exists($controller, $this->functionName)) {
            Handle::handle404();
        }

        // 通过反射解析控制器行为依赖参数注入
        $reflectionMethod = new \ReflectionMethod($controller, $this->functionName);
        $factory = Factory::getFactory();
        foreach ($reflectionMethod->getParameters() as $parameter) {
            $parameterType = $parameter->getClass();
            if ($parameterType) {
                // 获取依赖，并从工厂获取实例进行注入
                $this->parameter[] = $factory->get($parameterType->getName());
            } else {
                $this->parameter[] = null;
            }
        }
        // 注入参数执行
        return call_user_func_array(array($controller, $this->functionName), $this->parameter);
    }
}